module;
#include <QObject>
#include <QOpcUaClient>
#include <QOpcUaNode>
#include <QMap>
#include <QList>
#include <QString>
#include <QVariant>
#include <QDebug>
export module XYopcUa;

export class OpcUaClient : public QObject
{
    Q_OBJECT

public:
    explicit OpcUaClient(QObject *parent = nullptr);
    ~OpcUaClient();
    Q_INVOKABLE bool connectToEndpoint(const QString &address, quint16 port);
    Q_INVOKABLE void disconnectFromEndpoint();
    Q_INVOKABLE void readNode(const QString &nodeId);
    Q_INVOKABLE void readNodes(const QStringList &nodeIds);
    Q_INVOKABLE void writeNode(const QString &nodeId, const QVariant &value);
    Q_INVOKABLE void writeNodes(const QMap<QString, QVariant> &nodes);

signals:
    void connected();
    void nodesRead(const QMap<QString, QVariant> &values);
    void nodesWritten(const QMap<QString, bool> &results);
    void disconnected();
    void errorOccurred(const QString &error);
    void nodeValueRead(const QString &nodeId, const QVariant &value);
    void nodeValueWritten(const QString &nodeId, bool success);

public slots:
    void connectToEndpointSlot(const QString &address, quint16 port);
    void disconnectFromEndpointSlot();
    void readNodeSlot(const QString &nodeId);
    void readNodesSlot(const QStringList &nodeIds);
    void writeNodeSlot(const QString &nodeId, const QVariant &value);
    void writeNodesSlot(const QMap<QString, QVariant> &nodes);

private slots:
    void onStateChanged(QOpcUaClient::ClientState state);
    void onReadFinished(QOpcUa::NodeAttributes attr);
    void onWriteFinished(QOpcUa::NodeAttribute attr, QOpcUa::UaStatusCode status);
    void onBatchWriteFinished(QOpcUa::NodeAttribute attr, QOpcUa::UaStatusCode status);
private:
    QOpcUaClient *m_opcuaClient;
    QOpcUaNode *m_node;
    QString m_currentNodeId;
    QMap<QString, QVariant> m_pendingWrites;
    QMap<QString, bool> m_writeResults;
    QList<QOpcUaNode*> m_batchNodes;

};
